/* WiFi station Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "parameters.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"


static const char *TAG = __FILE_NAME__;


static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    ip_event_got_ip_t *event_got;

    if (event_base == WIFI_EVENT)
    {
        switch(event_id)
        {
            case WIFI_EVENT_STA_START:
                esp_wifi_connect();
                ESP_LOGI(TAG, "WIFI_EVENT_STA_START.");
                break;

            case WIFI_EVENT_STA_CONNECTED:
                ESP_LOGI(TAG, "WIFI_EVENT_STA_CONNECTED.");
                ptypeParameters->networkState |= BIT1;
                break;

            case WIFI_EVENT_STA_DISCONNECTED:
                ESP_LOGI(TAG, "WIFI_EVENT_STA_DISCONNECTED.");
                ptypeParameters->networkState &= ~BIT1;
                /* 已经配网，才自动重新连接 */
                if(ptypeParameters->networkState & BIT0)
                    esp_wifi_connect();
                break;

            default: break;
        }
    }
    else if (event_base == IP_EVENT)
    {
        switch(event_id)
        {
            case IP_EVENT_STA_GOT_IP:
                ESP_LOGI(TAG, "IP_EVENT_STA_GOT_IP.");
                event_got = (ip_event_got_ip_t *) event_data;
                ESP_LOGI(TAG, "Got IP:" IPSTR, IP2STR(&event_got->ip_info.ip));
                break;

            default: break;
        }
    }
}

/* Initialize wifi station */
void wifi_init_sta(char *ssid, char *password)
{
    wifi_config_t wifi_sta_config = {
        .sta = {
            .scan_method = WIFI_ALL_CHANNEL_SCAN,
            .failure_retry_cnt = 5,
            /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (password len => 8).
             * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
             * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
            * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
             */
            .threshold.authmode = strlen((char *)password) < 8 ? WIFI_AUTH_OPEN : WIFI_AUTH_WPA2_PSK,
            .sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
        },
    };

    strcpy((char *)wifi_sta_config.sta.ssid, ssid);
    strcpy((char *)wifi_sta_config.sta.password, password);

    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_sta_config));

    ESP_LOGI(TAG, "wifi_init_sta finished. SSID:%s password:%s", ssid, password);
}

void wifi_init(void)
{
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    esp_netif_t *esp_netif_sta;
    char cDatas[32] = {0};

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    esp_event_handler_instance_t instance_any_id;
    esp_event_handler_instance_t instance_got_ip;
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                        ESP_EVENT_ANY_ID,
                                                        &event_handler,
                                                        NULL,
                                                        &instance_any_id));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                        IP_EVENT_STA_GOT_IP,
                                                        &event_handler,
                                                        NULL,
                                                        &instance_got_ip));

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

    esp_netif_sta = esp_netif_create_default_wifi_sta();
    wifi_init_sta(ptypeParameters->WIFI_STA_SSID, ptypeParameters->WIFI_STA_PASSWORD);

    snprintf(cDatas, sizeof(cDatas), "DBS_%s", ptypeParameters->UID);
    esp_netif_set_hostname(esp_netif_sta, cDatas);

    ESP_ERROR_CHECK(esp_wifi_start());

    /* Set sta as the default interface */
    esp_netif_set_default_netif(esp_netif_sta);

    ESP_LOGI(TAG, "wifi_init_sta finished.");
}
